# -*- coding: utf-8 -*-
# created on 2017/01/19
from __future__ import division
from sympy import sympify, EmptySet
from mathsolver.functions.base import BaseBelong, BaseFunction, BaseSymbolValue, new_latex
from mathsolver.functions.hanshu.helper import check_inter, interval_to_baseineq, solveset, yizhizhiyu_qiufanwei
from mathsolver.functions.hanshu.jiou_qiujiexishi import JiOuJieXiShi
from mathsolver.functions.hanshu.dandiaoqujian import DanDiaoQuJian
from mathsolver.functions.budengshi.common_opers import ineq_expr_list_2_interval
from mathsolver.functions.hanshu.jiou_dandiao_budengshi import JiOuDanDiaoBuDengShi001
from mathsolver.functions.hanshu.zhouqi import has_f


class FenDuanHanShuJieBuDengShi(BaseFunction):
    """分段函数解不等式：格式为 f(x) < a 或者 f(x) < f(a)"""

    def solver(self, *args):
        func, ineq = args[0], args[1].value
        var, expr = func.var, func.expression
        left, op, right = sympify(ineq[0]), ineq[1], sympify(ineq[2])

        assert has_f(left), "不等式左边必须是 f(*) 格式，需要修改"
        left_var = left.args[0]

        # 如果右边为 f(a)，计算出
        if has_f(right):
            right_new = func.run(right.args[0])
            self.steps.append(["", "代入得 %s = %s" % (new_latex(right), right_new)])
            right = right_new

        # 分段解不等式组
        result = EmptySet()
        for piece_expr, piece_inter in expr:
            # 求属于某个区间时，参数满足的条件
            var_fanwei = yizhizhiyu_qiufanwei(left_var, piece_inter)
            self.steps.append(["", "当 %s ∈ %s 时：" % (new_latex(left_var), new_latex(piece_inter))])
            ineq = sympify('%s %s %s' % (str(piece_expr.subs(var, left_var)), op, right))
            symbols = ineq.free_symbols
            if symbols:
                left_var_symbol = symbols.pop()
                solve_piece = solveset(ineq)
                piece_result = solve_piece.intersect(var_fanwei)
                result = result.union(piece_result)
                self.steps.append(["", "解得 %s ∈ %s" % (new_latex(left_var_symbol), new_latex(piece_result))])
            elif ineq is True:
                result = result.union(piece_inter)
                self.steps.append(["", "不等式在区间上恒成立"])
            elif ineq is False:
                self.steps.append(["", "不等式在区间始终不成立"])
            else:
                raise ValueError("known type")

        self.steps.append(["", "所以 %s 的解为 %s ∈ %s" % (args[1].printing(), new_latex(left_var_symbol), new_latex(result))])
        self.output.append(BaseSymbolValue({left_var_symbol: result}))
        self.label.add('分段函数解不等式')
        return self


class FenDuanHanShuJieBuDengShiJiOu(BaseFunction):
    """解分段函数不等式——奇偶性"""

    def solver(self, *args):
        jiou, ineq_or_belong, func, ineq = args

        if isinstance(ineq_or_belong, BaseBelong):
            x, interval = ineq_or_belong.value[0], check_inter(ineq_or_belong.value[2])
            ineq_or_belong = interval_to_baseineq(x, interval)

        # 根据函数奇偶性求解析式
        step_solver = JiOuJieXiShi().solver(jiou, ineq_or_belong, func)
        self.steps.extend(step_solver.steps)
        jiexishi = step_solver.output[0]

        # 分段函数解不等式
        fenduan_solver = FenDuanHanShuJieBuDengShi().solver(jiexishi, ineq)
        self.steps.extend(fenduan_solver.steps)
        self.output = fenduan_solver.output
        self.label.add("解分段函数不等式——奇偶性")
        return self


class FenDuanHanShuJieBuDengShiJiOuDanDiao(BaseFunction):
    """解分段函数不等式——奇偶性+单调性"""

    def solver(self, *args):
        jiou, ineq, func, q_ineq = args

        # 计算单调区间
        up, down = DanDiaoQuJian().solver(func).output[0].value

        # 判断函数在单侧的单调性
        ineq_inter = ineq_expr_list_2_interval(ineq.value)
        if ineq_inter.is_subset(up):
            step_solver = JiOuDanDiaoBuDengShi001().solver(
                jiou, up, '增', q_ineq)
            step_solver.steps.insert(0, ['', '函数 %s 在 %s 上 单调增' % (func.printing(), ineq_inter)])
            return step_solver
        elif ineq_inter.is_subset(down):
            step_solver = JiOuDanDiaoBuDengShi001().solver(
                jiou, down, '减', ineq)
            step_solver.steps.insert(0, ['', '函数 %s 在 %s 上 单调减' % (func.printing(), ineq_inter)])
            return step_solver
        else:
            raise ValueError("don't match, use dairu_jiebudengshi_001")


if __name__ == '__main__':
    pass
